#include "bootloader.h"
#include <stdbool.h>

// 更新进程
static UpgradeProcess_e  upgrade_process = UPGRADE_START;
// 当前需要复制的下载区的地址
static uint32_t current_down_addr = DOWNLOAD_SECTOR_ADDR;
// 当前目标APP的地址
static uint32_t current_app_addr = APP_SECTOR_ADDR;
// 重置状态函数
static void UpgradeProcessReset(void);

/**
 * @desc  : 读取setting中的启动模式
 * @date  : 2025-09-09
 * @author: AnRui
 * @return: uint8_t
 * @note  : 返回值 0: 读取setting失败
 *          返回值 1: 正常的启动模式
 *          返回值 2: 升级模式
 */
bool ReadSettingStartUpMode(uint8_t* mode)
{
    bool result = READ_DATA_FROM_FLASH(SETTING_SECTOR_ADDR, mode, 1);
    if (!result) return false;// 读取setting失败
    return true;
}


/**
 * @desc  : APP升级
 * @date  : 2025-09-09
 * @author: AnRui
 * @return: UpgradeProcess_e
 * @note  : 将app数据从下载区复制到app区域
 */
UpgradeProcess_e  AppUpgrade(void)
{
    // 128字节复制缓冲区
    uint8_t copy_buf[UPGRADE_BUFF_SIZE] = { 0 };

    switch (upgrade_process) {
    case UPGRADE_START:
        upgrade_process = UPGRADE_ING;
        break;
    case UPGRADE_ING:
        if (current_down_addr >= (DOWNLOAD_SECTOR_ADDR + DOWNLOAD_SECTOR_SIZE)) {
            upgrade_process = UPGRADE_SUCCESS;
        } else {
            if (!READ_DATA_FROM_FLASH(current_down_addr, copy_buf, UPGRADE_BUFF_SIZE))   upgrade_process = UPGRADE_ERROR;
            current_down_addr += UPGRADE_BUFF_SIZE;
            if (!WRITE_DATA_TO_FLASH(current_app_addr, copy_buf, UPGRADE_BUFF_SIZE))   upgrade_process = UPGRADE_ERROR;
            current_app_addr += UPGRADE_BUFF_SIZE;
            printf("Upgrade:%% %d\r\n", (current_down_addr - DOWNLOAD_SECTOR_ADDR) / DOWNLOAD_SECTOR_SIZE);
        }
        break;
    case UPGRADE_ERROR:
        UpgradeProcessReset();
        return UPGRADE_ERROR;
    case UPGRADE_SUCCESS:
        UpgradeProcessReset();
        return UPGRADE_SUCCESS;
    default:
        break;
    }
    return upgrade_process;
}



/**
 * @desc  : 跳转到APP执行
 * @date  : 2025-09-09
 * @author: AnRui
 * @param : app_addr - {参数说明}:
 * @return: bool
 * @note  : 升级完成后 跳转到APP执行
* 缺一个 重置中断向量表
 */
bool JumpAppRun(void)
{
    // 获取APP中的 堆栈指针
    uint32_t stack_top_addr = *(__IO uint32_t*)APP_SECTOR_ADDR;
    // 检测堆栈指针是否合法
    if (stack_top_addr > RAM_START_ADDRESS && stack_top_addr <= (RAM_START_ADDRESS + RAM_SIZE)) {
        //关闭全局中断 避免在新的中断向量表就位之前产生中断
        __disable_irq();
        // 设置App的栈顶指针 MSP 
        __set_MSP(stack_top_addr);
        // 获取APP中的 Reset_Handler函数的起始地址
        uint32_t Reset_Handler_addr = *(__IO uint32_t*)(APP_SECTOR_ADDR + 4);
        // 转成函数指针
        jump_callback cb = (jump_callback)Reset_Handler_addr;
        // 执行Reset_Handler
        cb();
        return true;
    }
    return false;
}


/**
 * @desc  : 设置下一次bootloader的启动模式
 * @date  : 2025-09-09
 * @author: AnRui
 * @param : process - {参数说明}:
 * @note  :
 */
bool SetFlashSetting(StartUpMode_e BootLoaderStartMode)
{
    uint8_t tmp = (uint8_t)BootLoaderStartMode;
    return WRITE_DATA_TO_FLASH(SETTING_SECTOR_ADDR, &tmp, 1);
}

/**
* @desc  :重置升级状态（升级完成/失败后调用）
* @date  : 2025-09-11
* @author: AnRui
* @note  :
*/
static void UpgradeProcessReset(void)
{
    current_down_addr = DOWNLOAD_SECTOR_ADDR;
    current_app_addr = APP_SECTOR_ADDR;
    upgrade_process = UPGRADE_START;
}

